package com.etop.bank.activity;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.etop.BankCard.BankCardAPI;
import com.etop.BankCard.BankCardInfoAPI;
import com.etop.bank.model.OcrKeyDatas;
import com.etop.bank.utils.BankConfig;
import com.etop.bank.utils.NV21ToARGBUtil;
import com.etop.bank.utils.StatusBarUtil;
import com.etop.bank.utils.StreamUtil;
import com.etop.bank.view.ScanRectView;
import com.etop.camera.CommonCameraView;
import com.example.bank_ocr.R;

import java.io.File;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BankScanActivity extends Activity implements CommonCameraView.PreviewFrameListener, View.OnClickListener {

	private ImageButton mIbBack; // 返回按钮
	private TextView mTvTishi;  // 提示文字
	private TextView mTvTishi_v;
	private ImageView mIvScanLine;  // 扫描线
	private ImageView mIvFlashLight;  // 手电筒图标
	private LinearLayout mLlFlashLight;  // 手电筒布局
	private RelativeLayout mRootLayout;
	private ScanRectView scanRectView;  // 扫描框布局
	private FrameLayout mFrameLayout;
	private CommonCameraView mCameraView;  // 相机view
	private ImageButton changeDirection;  // 横竖屏切换按钮

	private int preWidth;
	private int preHeight;
	private int screenWidth;
	private int screenHeight;
	// 识别中标识
	private boolean isRecog = true;
	// 横竖屏识别参数
	private boolean isVertical;
	// 手电筒
	private boolean isFlashOn = false;

	// 坐标集
	private int[] borders = new int[4];
	// 核心对象
	private BankCardAPI bankApi;
	private BankCardInfoAPI cardinfoapi;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		StatusBarUtil.setTranslucent(this);
		setContentView(R.layout.activity_bank_scan);
		// 初始化view
		initView();
        // 初始化数据
		initData();
        // 初始化OCR
		initOCR();
		// 设置横竖屏布局
		setLayoutOrientation(isVertical);
		// 初始化动画
		initAnimation();
	}

	/**
	 * 初始化view
	 */
	private void initView() {
		screenWidth = getWindowManager().getDefaultDisplay().getWidth();
		screenHeight = getWindowManager().getDefaultDisplay().getHeight();
		mRootLayout = (RelativeLayout) findViewById(R.id.etop_bank_root_layout);
		mIbBack = (ImageButton) findViewById(R.id.etop_bank_title_back);
		changeDirection = (ImageButton) findViewById(R.id.title_ib_right);

		mFrameLayout = (FrameLayout) findViewById(R.id.etop_bank_frame_layout);
		mTvTishi = (TextView) findViewById(R.id.etop_bank_tv_tishi);
		mTvTishi_v = (TextView) findViewById(R.id.etop_bank_tv_tishi_h);
		mLlFlashLight = (LinearLayout) findViewById(R.id.etop_bank_ll_flashlight);
		mIvFlashLight = (ImageView) findViewById(R.id.etop_bank_iv_flashlight);
		mIvScanLine = (ImageView) findViewById(R.id.etop_bank_iv_scanline);
		scanRectView = (ScanRectView) findViewById(R.id.etop_bank_srv_view);

		mIbBack.setOnClickListener(this);
		mLlFlashLight.setOnClickListener(this);
		changeDirection.setOnClickListener(this);

		// 初始化相机布局
		mCameraView = new CommonCameraView(this, screenWidth, screenHeight, CommonCameraView.LOW);
		mFrameLayout.addView(mCameraView);

		// 相机适配回调
		mCameraView.setOnCameraSizeListener(new CommonCameraView.CameraSizeListener() {
			@Override
			public void setCameraSize(int[] size) {
				if (size != null) {
					preWidth = size[0];
					preHeight = size[1];
					setRecogRegion();
					mCameraView.setOnPreviewFrameListener(BankScanActivity.this);
					//拿到适配的相机预览比例
					double previewScale = preHeight / (double) preWidth;
					//拿到真实的屏幕比例
					double screenScale = screenWidth / (double) screenHeight;
					//预览的和实际显示的差距较大
					if (Math.abs(previewScale - screenScale) > 0) {
						//说明屏幕长，适配的预览比例大（比如三星S系列）
						if (previewScale > screenScale) {
							ViewGroup.LayoutParams layoutParams = mRootLayout.getLayoutParams();
							int height = (int) (screenWidth / previewScale);
							layoutParams.height = height;
							mRootLayout.setLayoutParams(layoutParams);
							screenHeight = height;
						}
					}
				} else {
					Toast.makeText(BankScanActivity.this, "请开启相机权限", Toast.LENGTH_SHORT).show();
				}
			}
		});
	}

	/**
	 * 初始化数据
	 */
	private void initData() {
		// 横竖屏标识
		isVertical = getIntent().getBooleanExtra(OcrKeyDatas.RECOG_TYPE, true);

		// 判断配置参数
		if (!BankConfig.isDriection){
			changeDirection.setVisibility(View.GONE);
		}
		if (!BankConfig.isScanLine){
			mIvScanLine.setVisibility(View.GONE);
		}
		//创建保存图像的目录
		File file = new File(BankConfig.saveImagePath);
		if (!file.exists() || !file.isDirectory()) {
			file.mkdirs();
		}
	}

	/**
	 * 初始化OCR核心
	 */
	private void initOCR() {
		bankApi = BankCardAPI.getBankInstance();
		int initKernalCode = bankApi.initBankKernal(this);
		if (initKernalCode == 0) {
			if (cardinfoapi == null) {
				cardinfoapi = new BankCardInfoAPI();
				cardinfoapi.InitCardInfo();
			}
			String endTime = bankApi.GetEndTime();
			Log.e("BankScanActivity", "授权截止日期 ------------- " + endTime);
		} else {
			mTvTishi.setText("OCR核心激活失败:" + initKernalCode + "\r\n错误信息：" + BankConfig.getErrorInfo(initKernalCode));
		}
	}

	/**
	 * 初始化动画
	 */
	private TranslateAnimation horizontalAnimation;

	private void initAnimation() {
		if (horizontalAnimation != null) {
			horizontalAnimation.cancel();
			mIvScanLine.clearAnimation();
		}
		if (!isVertical) {
			int startX = (int) (screenWidth * 0.36);
			int stopX = -(int) (screenWidth * 0.36);
			// x轴移动距离
			horizontalAnimation = new TranslateAnimation(startX, stopX, 0, 0);
		} else {
			int rectHeight = (int) (screenHeight / 1.45);
			int startY = -(screenHeight - rectHeight) / 2;
			int stopY = (screenHeight - rectHeight) / 2;
			horizontalAnimation = new TranslateAnimation(0, 0, startY, stopY);
		}
		horizontalAnimation.setDuration(2000); // 动画持续时间
//        horizontalAnimation.setRepeatMode(Animation.REVERSE);//反转位移
		horizontalAnimation.setRepeatCount(Animation.INFINITE); // 无限循环
		//播放动画
		mIvScanLine.startAnimation(horizontalAnimation);
	}

	/**
	 * 鉴定
	 * @param view
	 */
	@Override
	public void onClick(View view) {
		int viewId = view.getId();
		if (viewId == R.id.etop_bank_title_back) {
			finish();
		} else if (viewId == R.id.etop_bank_ll_flashlight) {
			isFlashOn = !isFlashOn;
			boolean isSupport = mCameraView.alterFlash(isFlashOn ? 3 : 2);
			if (isSupport) {
				mIvFlashLight.setBackgroundResource(isFlashOn ? R.mipmap.flash_light_on : R.mipmap.flash_light);
			} else {
				Toast.makeText(this, "当前设备不支持闪光灯", Toast.LENGTH_SHORT).show();
			}
		} else if (viewId == R.id.title_ib_right) { // 改变方向
			// 设置横竖屏布局
			isVertical = !isVertical;
			setLayoutOrientation(isVertical);
			setRecogRegion();
			initAnimation();
		}
	}

	/**
	 * 识别线程
	 */
	private ThreadPoolExecutor recogTPE = new ThreadPoolExecutor(1, 1, 1,
			TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
	private char[] recogval = new char[30];
	private int[] pLineWarp = new int[32000];
	private int[] line = new int[4];

	/**
	 * 视频流回调
	 * @param data
	 */
	@Override
	public void setPreviewFrame(final byte[] data) {
		if (isRecog) {
			isRecog = false;
			recogTPE.execute(new Runnable() {
								 @Override
								 public void run() {
									 synchronized (this) {
										 processFrame(data);
									 }
								 }
							 }
			);
		}
	}

	private void processFrame(byte[] frameData) {
		recogval = new char[30];
		//调用识别接口进行识别
//		int recogCode = bankApi.ScanStreamNV21(frameData, preWidth, preHeight, line, recogval, pLineWarp);
		int recogCode = bankApi.ScanStreamNV21Ex(frameData, preWidth, preHeight, line, recogval, pLineWarp, orientation);
		Log.e("recogCode:", recogCode + "");
		if (recogCode == 0) {//识别成功
			isRecog = false;
			Vibrator mVibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
			mVibrator.vibrate(100);
			String[] cardinfo = new String[4];
			//调用获取识别结果接口获取识别结果
			cardinfoapi.GetCardInfo(recogval, cardinfo);
			//获取银行卡号
			String str = String.valueOf(recogval);
			String regEx = "[^0-9]";
			Pattern p = Pattern.compile(regEx);
			Matcher m = p.matcher(str);
			String bankNumber = m.replaceAll("").trim();
			//获取银行名称
			String bankName = cardinfo[0];
			//获取银行代码
			String bankCode = cardinfo[1];
			//获取卡名称
			String cardName = cardinfo[2];
			//获取卡类型
			String cardType = cardinfo[3];
//            Log.e("识别成功", "bankNumber:" + bankNumber + ",bankName:" + bankName + ",bankCode:" + bankCode
//                    + ",cardName:" + cardName + ",cardType:" + cardType);
			HashMap<String, String> hashMap = new HashMap<>();
			//将识别完成后，获取识别结果，添加到集合中
			hashMap.put(OcrKeyDatas.BANK_KEY[0], bankNumber);
			hashMap.put(OcrKeyDatas.BANK_KEY[1], bankName);
			hashMap.put(OcrKeyDatas.BANK_KEY[2], cardName);
			hashMap.put(OcrKeyDatas.BANK_KEY[3], bankCode);
			hashMap.put(OcrKeyDatas.BANK_KEY[4], cardType);

			// 保存图片
			File file = new File(BankConfig.saveImagePath);
			String bankPath = "";
			String imagePath = "";
			if (file.exists() && file.isDirectory()) {
				if (BankConfig.isSaveCrop) {
					Bitmap bitmapSamll = Bitmap.createBitmap(pLineWarp, 400, 80, Bitmap.Config.RGB_565);
					bankPath = new StreamUtil().saveBitmapFile(bitmapSamll, BankConfig.saveImagePath, "Bank");
					bitmapSamll.recycle();
				}
				if (BankConfig.isSaveImage) {
					int[] argb8888 = new NV21ToARGBUtil().convertYUV420_NV21toARGB8888(frameData, preWidth, preHeight);
					//创建全屏的bitmap
					Bitmap bitmap = Bitmap.createBitmap(argb8888, preWidth, preHeight, Bitmap.Config.RGB_565);
					// 如果是竖屏旋转图片
					if (isVertical) {
						bitmap = StreamUtil.BitmapRotation(bitmap, 90);
					}
					Bitmap bitmapRegion = Bitmap.createBitmap(bitmap, borders[0], borders[1], borders[2] - borders[0], borders[3] - borders[1]);
					imagePath = new StreamUtil().saveBitmapFile(bitmapRegion, BankConfig.saveImagePath, "Image");
					bitmap.recycle();
				}
			}

			Intent intent = new Intent();
			intent.putExtra(OcrKeyDatas.RECOG_CODE, recogCode);
			intent.putExtra(OcrKeyDatas.RECOG_RESULT_HASHMAP, hashMap);
			if (!TextUtils.isEmpty(bankPath))
				intent.putExtra(OcrKeyDatas.CROP_PATH, bankPath);
			if (!TextUtils.isEmpty(imagePath))
				intent.putExtra(OcrKeyDatas.IMAGE_PATH, imagePath);
			BankScanActivity.this.setResult(RESULT_OK, intent);
			BankScanActivity.this.finish();
		} else {
			isRecog = true;
		}

	}


	/**
	 * 设置识别区域
	 */
	private int orientation = 0;

	public void setRecogRegion() {
		if (bankApi != null) {
			orientation = 0;
			int left, top, right, bottom;
			if (!isVertical) {
				// 横屏银行卡
				top = (int) (preHeight * BankConfig.TOP_H_SCALE);
				bottom = preHeight - top;
				int rectHeight = (int) ((bottom - top) * BankConfig.SCAN_SCALE);
				left = (preWidth - rectHeight) / 2;
				right = rectHeight + left;
				borders[0] = left;
				borders[1] = top;
				borders[2] = right;
				borders[3] = bottom;
			} else {
				//设置竖向识别区域
				orientation = 1;
				left = 0;
				right = preHeight;
				int rectHeight = (int) ((right - left) / BankConfig.BUTTOM_V_SCALE);
				top = (preWidth - rectHeight) / 2;
				bottom = rectHeight + top;
				borders = new int[]{left, top, right, bottom};
			}
			bankApi.SetRegion(left, top, right, bottom);
		}
	}

	/**
	 * 设置横竖屏布局
	 */
	private void setLayoutOrientation(boolean isVertical) {
		// 设置扫描框放向
		scanRectView.setIsVertical(isVertical);
		int rectHeight = (int) (screenWidth * 1.1248);
		// 手电筒
		int topkMargin = (screenHeight - rectHeight) / 2;
		RelativeLayout.LayoutParams flashLp = (RelativeLayout.LayoutParams) mLlFlashLight.getLayoutParams();
		flashLp.topMargin = topkMargin + (int) (rectHeight * 1.1);
		mLlFlashLight.setLayoutParams(flashLp);
		if (isVertical) {
			// 提示语
			RelativeLayout.LayoutParams lpTiShi = (RelativeLayout.LayoutParams) mTvTishi_v.getLayoutParams();
			lpTiShi.topMargin = (screenHeight / 2) - 140;//设置顶部的距离
			mTvTishi_v.setLayoutParams(lpTiShi);
			mTvTishi_v.setRotation(0);
			mTvTishi_v.setVisibility(View.VISIBLE);
			mTvTishi.setVisibility(View.GONE);
			// 扫描线
			int marTop = (screenHeight + rectHeight) / 2;
			mIvScanLine.setBackgroundResource(R.mipmap.scan_line_h);
			RelativeLayout.LayoutParams lpFlash = (RelativeLayout.LayoutParams) mIvScanLine.getLayoutParams();
			lpFlash.topMargin = marTop;
			lpFlash.width = (int) (screenWidth * 0.95);
			lpFlash.height = (int) (8);
			mIvScanLine.setLayoutParams(lpFlash);
		} else {
			// 提示语
			RelativeLayout.LayoutParams lpTiShi = (RelativeLayout.LayoutParams) mTvTishi.getLayoutParams();
			lpTiShi.leftMargin = screenWidth / 2;//设置顶部的距离
			mTvTishi.setLayoutParams(lpTiShi);
			mTvTishi.setRotation(90);
			mTvTishi_v.setVisibility(View.GONE);
			mTvTishi.setVisibility(View.VISIBLE);
			// 扫描线
			RelativeLayout.LayoutParams scanLp = (RelativeLayout.LayoutParams) mIvScanLine.getLayoutParams();
			scanLp.topMargin = 0;
			scanLp.width = (int) (8);
			scanLp.height = (int) (rectHeight * 0.95);
			mIvScanLine.setLayoutParams(scanLp);
			mIvScanLine.setBackgroundResource(R.mipmap.scan_line);
		}
	}

	@Override
	protected void onDestroy() {
		bankApi.releaseKernal();
		super.onDestroy();
	}
}
